#include "1signal.h"
#include "main.h"
const double PI = 3.14159265359;

void Loadingtime(int repeatCount) {
    for (int i = 0; i < repeatCount; ++i) {
        cout << "\rProcessing"; 
        for (int j = 0; j <= i % 5; ++j) {
            cout << "."; 
        }
        cout.flush(); 
        this_thread::sleep_for(chrono::milliseconds(500)); 
    }
    cout << endl; 
    cout << "\033c";
}
//200, 10, 0.2, 63
SignalGenerator::SignalGenerator()
: num_points(100), frequency(5.0), sampling_rate(100.0), amplitude(1.0), noise_amplitude(0.5), high_noise_frequency(40.0) {
    srand(time(0)); // Seed for random noise generation
}

SignalGenerator::~SignalGenerator() {}

void SignalGenerator::configure() {
    Loadingtime(5);  

    cout << "\n******************************************" << endl;
    cout << "*     Signal and noise Generator Tool    *" << endl;
    cout << "******************************************" << endl;

    std::cout << "Enter the Sampling rate: ";
    std::cin >> sampling_rate;

    std::cout << "Enter the frequency (frequency of the sin wave): ";
    std::cin >> frequency;

    std::cout << "Enter the noise amplitude (maximum noise amplitude): ";
    std::cin >> noise_amplitude;

    std::cout << "Enter the high-frequency noise frequency: ";
    std::cin >> high_noise_frequency;
    
}

void SignalGenerator::generate_signal() {
    std::ofstream outFile("2signal_data.csv");
    if (!outFile.is_open()) {
        std::cerr << "Failed to open file for writing." << std::endl;
        return;
    }

    for (int i = 0; i < num_points; ++i) {
        double t = i / sampling_rate; // compute time
        double base_signal = amplitude * fabs(sin(2 * PI * frequency * t)); 
        double high_freq_noise = noise_amplitude * sin(2 * PI * high_noise_frequency * t); // noisy frequency
        double noisy_signal = base_signal + high_freq_noise; 

        outFile << t << ", " << noisy_signal << std::endl; 
    }
    outFile.close();
}


void SignalGenerator::showresults(){

        cout << "\n******************************************" << endl;
        cout << "*        Parameter setting results       *" << endl;
        cout << "******************************************" << endl;
        cout << "Please check the parameter setting!\n";
        cout << "Sampling rate: " << sampling_rate << endl;
        cout << "frequency of the wave: " << frequency << endl;
        cout << "maximum noise amplitude: " << noise_amplitude << endl;
        cout << "high-frequency noise frequency: " << high_noise_frequency << endl; 
}

void SignalGenerator::start() {
    char continueGenerating = 'y';
    do {
        configure();
        generate_signal();

        std::cin >> continueGenerating;
    } while (continueGenerating == 'y' || continueGenerating == 'Y');
}

// A total function is created to encapsulate the entire signal generation process
void run_signal_generator() {
    SignalGenerator signalGen;

    char continueGenerating = 'y';
    do {
        // Configuring and generating signals
        signalGen.configure();
        Loadingtime(5);
        signalGen.generate_signal();
        signalGen.showresults();

        // Indicates whether to continue generating signals
        std::cout << "Do you want to modify the generated signal? (y/n): ";
        std::cin >> continueGenerating;
    } while (continueGenerating == 'y' || continueGenerating == 'Y');
}

void filter_menu() {
    int choice;
    SignalGenerator signalGen;
    Loadingtime(5);

    cout << "\n******************************************" << endl;
    cout << "*     Signal and Noise Generator Tool    *" << endl;
    cout << "******************************************" << endl;
    cout << "1. Start signal filtering" << endl;
    cout << "2. Look at the schematic diagram of the filter" << endl;
    cout << "3. Exit" << endl;
    cout << "Enter your choice: ";
    cin >> choice;

    switch (choice) {
        case 1:
// signalGen.configure();
            run_signal_generator(); 
            process_signal();
            break;
        case 2:
            displayFilterSchematic();
            break;
        case 3:
            exitApplication();
            return;  // Exit the loop in main
        default:
            cout << "Invalid choice. Please enter a valid number (1-3)." << endl;
            break;
    }
}

// Function to display the filter schematic
void displayFilterSchematic() {
    std::cout << "             R             \n";
    std::cout << "Vin ----/\\/\\/\\/\\-----+----- Vout\n";
    std::cout << "                      |     \n";
    std::cout << "                      |     \n";
    std::cout << "                      C     \n";
    std::cout << "                      |     \n";
    std::cout << "                      |     \n";
    std::cout << "                     GND    \n";
}

// Function to exit the application
void exitApplication() {
    cout << "Exiting the application..." << endl;
//  exit(0);
}